package com.youlu.campus.service.ca.impl;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.CaActivityLevel;
import com.youlu.campus.entity.CaTemplate;
import com.youlu.campus.entity.CertificateActivityConfig;
import com.youlu.campus.entity.VO.req.CaActivityLevelVO;
import com.youlu.campus.entity.VO.req.CopyCaCertificateConfigReq;
import com.youlu.campus.entity.VO.req.CreateCertificateActivityConfigReq;
import com.youlu.campus.entity.VO.req.QueryCertActivityConfigReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CertificateActivityConfigService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Lazy
    @Autowired
    private CaCertificateConfigService caCertificateConfigService;

    public List<CertificateActivityConfig> findByActivityId(String activityId){
         Query query = new Query();
         query.addCriteria(Criteria.where("activityId").is(activityId));
        List<CertificateActivityConfig> list = this.mongoTemplate.find(query, CertificateActivityConfig.class);
        if(CollectionUtils.isNotEmpty(list)){
            return list;
        }
        return null;
    }

    public void saveOrUpdate(CreateCertificateActivityConfigReq createCertificate) {
        log.info("新增编辑修改活动证书配置 - > {}", JSON.toJSONString(createCertificate));
        String id = createCertificate.getId();
        String activityId = createCertificate.getActivityId();
        String activityName = createCertificate.getActivityName();
        log.info("配置活动 - > {} 证书", activityName);
        CertificateActivityConfig certificateActivityConfig = null;
        if (StringUtils.isNotBlank(id)) {
            certificateActivityConfig = mongoTemplate.findById(id, CertificateActivityConfig.class);
            certificateActivityConfig.setUpdatedTime(new Date());
        } else {
            certificateActivityConfig = new CertificateActivityConfig();
            certificateActivityConfig.setCreatedTime(new Date());
        }
        certificateActivityConfig.setActivityId(activityId);
        certificateActivityConfig.setActivityName(activityName);
        certificateActivityConfig.setCaType(createCertificate.getCaType());
        certificateActivityConfig.setCertificateName(createCertificate.getCertificateName());
        CaActivityLevelVO[] caActivityLevelArray = createCertificate.getCaActivityLevel();
        CaActivityLevel[] caActivityLevel = new CaActivityLevel[caActivityLevelArray.length];
        for (int i = 0; i < caActivityLevelArray.length; i++) {
            CaActivityLevel newActivityLevel = new CaActivityLevel();
            if (Objects.nonNull(caActivityLevelArray[i]) && StringUtils.isBlank(caActivityLevelArray[i].getCaLevelCode())) {
                newActivityLevel.setCaLevelCode(new ObjectId().toString());
            } else {
                newActivityLevel.setCaLevelCode(caActivityLevelArray[i].getCaLevelCode());
            }
            newActivityLevel.setCaLevel(caActivityLevelArray[i].getCaLevel());
            caActivityLevel[i] = newActivityLevel;
        }
        certificateActivityConfig.setLetterStart(createCertificate.getLetterStart());
        certificateActivityConfig.setCaActivityLevel(caActivityLevel);
        certificateActivityConfig.setCaTime(createCertificate.getCaTime());
        this.mongoTemplate.save(certificateActivityConfig);
    }

    public Page<CertificateActivityConfig> list(QueryCertActivityConfigReq queryCertActivityConfigReq) {
        Integer page = queryCertActivityConfigReq.getPage();
        Integer pageSize = queryCertActivityConfigReq.getPageSize();
        String activityId = queryCertActivityConfigReq.getActivityId();
        Query query = new Query();
        if (StringUtils.isNotBlank(activityId)) {
            query.addCriteria(Criteria.where("activityId").is(activityId));
        }
        if (StringUtils.isNotBlank(queryCertActivityConfigReq.getCertificateName())) {

            Pattern pattern = Pattern.compile("^.*" + queryCertActivityConfigReq.getCertificateName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("certificateName").regex(pattern));
        }
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize);
        long count = this.mongoTemplate.count(query, CertificateActivityConfig.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<CertificateActivityConfig> list = this.mongoTemplate.find(query.with(pageRequest), CertificateActivityConfig.class);
        list.stream().forEach(certificateActivityConfig -> {

            ActivityInfo activityInfo = this.mongoTemplate.findById(certificateActivityConfig.getActivityId(), ActivityInfo.class);
            if(Objects.nonNull(activityInfo)){
                certificateActivityConfig.setActivityName(activityInfo.getName());
            }
        });
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    public CertificateActivityConfig detail(String id) {
        return this.mongoTemplate.findById(id, CertificateActivityConfig.class);
    }

    public CertificateActivityConfig findByActivityIdAndBizType(String activityId, String taskBizType) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("caType").is(taskBizType));
        CertificateActivityConfig certificateActivityConfig = this.mongoTemplate.findOne(query, CertificateActivityConfig.class);
        if (Objects.isNull(certificateActivityConfig)) {
            throw new BusinessException("未配置该活动等级");
        }
        return certificateActivityConfig;
    }

    public Map<String, List<CertificateActivityConfig>> getByIds(Set<String> idsSet) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").in(idsSet));
        List<CertificateActivityConfig> list = this.mongoTemplate.find(query, CertificateActivityConfig.class);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().collect(Collectors.groupingBy(certificateActivityConfig -> certificateActivityConfig.getActivityId()));
    }

    //@Async
    public void doCopyCertificateConfig(String copyActivityId,String targetActivityId){
        log.info("【copy 活动证书配置】开始复制活动证书配置 sourceActivityId->{} | newTargetActivityId->{}",copyActivityId, targetActivityId);
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(copyActivityId));
        List<CertificateActivityConfig> list = this.mongoTemplate.find(query, CertificateActivityConfig.class);
         if(CollectionUtils.isEmpty(list)){
             log.error("【copy 活动证书配置】结束复制活动证书配置 未查询到证书配置信息 sourceActivityId->{} | newTargetActivityId->{}", copyActivityId, targetActivityId);
             return;
         }
         Date now = new Date();
        List<CertificateActivityConfig> targetCertificateActivityConfigList = list.stream().peek(certificateActivityConfig -> {
            String oldCertificateConfigId = certificateActivityConfig.getId();
            certificateActivityConfig.setId(ObjectId.get().toString());
            certificateActivityConfig.setActivityId(targetActivityId);
            certificateActivityConfig.setCreatedTime(now);
            certificateActivityConfig.setUpdatedTime(now);
            certificateActivityConfig.setCertificateName(certificateActivityConfig.getCertificateName());
            CopyCaCertificateConfigReq copyCaCertificateConfigReq = new CopyCaCertificateConfigReq();
            copyCaCertificateConfigReq.setCopyActivityId(copyActivityId);
            copyCaCertificateConfigReq.setCopySourceCertificateId(oldCertificateConfigId);
            copyCaCertificateConfigReq.setTargetCopyActivityId(targetActivityId);
            copyCaCertificateConfigReq.setCopyTargetCertificateId(certificateActivityConfig.getId());
            caCertificateConfigService.copyCaCertificateConfig(copyCaCertificateConfigReq);
        }).collect(Collectors.toList());
        this.mongoTemplate.insertAll(targetCertificateActivityConfigList);
        log.info("【copy 活动证书配置】结束复制活动证书配置 sourceActivityId->{} | newTargetActivityId->{}",copyActivityId, targetActivityId);

    }


}
